#include "nvic.h"

// setup the hardware independent watchdog
// 初始化并开启独立看门狗
uint16_t runIWDGInit(int ms)
{
#ifndef RUN_ENABLE_IWDG
    return 0;
#else
    uint16_t prevReloadVal = 0;
    int reloadVal;

    IWDG_ReloadCounter();//喂狗

    DBGMCU_Config(DBGMCU_IWDG_STOP, ENABLE);//当在jtag调试的时候.停止看门狗

    // IWDG timeout equal to 10 ms (the timeout may varies due to LSI frequency dispersion)
    // Enable write access to IWDG_PR and IWDG_RLR registers
    IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//允许访问IWDG_PR和IWDG_RLR寄存器

    // IWDG counter clock: LSI/4
    IWDG_SetPrescaler(IWDG_Prescaler_4);

    // Set counter reload value to obtain 10ms IWDG TimeOut.
    //  Counter Reload Value	= 10ms/IWDG counter clock period
    //				= 10ms / (RUN_LSI_FREQ/4)
    //				= 0.01s / (RUN_LSI_FREQ/4)
    //				= RUN_LSI_FREQ/(4 * 100)
    //				= RUN_LSI_FREQ/400
    reloadVal = RUN_LSI_FREQ*ms/4000;

    if (reloadVal < 1)
        reloadVal = 1;
    else if (reloadVal > 0xfff)
        reloadVal = 0xfff;

    prevReloadVal = IWDG->RLR;

    IWDG_SetReload(reloadVal);

    // Reload IWDG counter
    IWDG_ReloadCounter();

    // Enable IWDG (the LSI oscillator will be enabled by hardware)
    IWDG_Enable();

    return (prevReloadVal*4000/RUN_LSI_FREQ);
#endif
}

//执行看门狗喂狗
void runFeedIWDG(void) {
#ifdef RUN_ENABLE_IWDG
    IWDG_ReloadCounter();
#endif
}

int NVIC_CC1101GD0(FunctionalState state)
{
    NVIC_InitTypeDef NVIC_InitStructure;

    /* Set NVIC Grouping to 16 groups of interrupt without sub-grouping */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

    /* Enable and set EXTI Interrupt to the lowest priority */
    NVIC_InitStructure.NVIC_IRQChannel = GD0IRQ_EXTI_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 15;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = state;

    NVIC_Init(&NVIC_InitStructure);
    return 0;
}

int Is_CCxxx0_IRQ_enabled(void)
{
    return ((   NVIC->ISER[((uint32_t)(GD0IRQ_EXTI_IRQn) >> 5)]
            & (uint32_t)0x01 << (GD0IRQ_EXTI_IRQn & (uint8_t)0x1F)  ) ? 1 : 0) ;
}

int CC1101_ISR_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);

    // Enable GPIO used as DECA IRQ for interrupt
    GPIO_InitStructure.GPIO_Pin = GD0IRQ;
    GPIO_InitStructure.GPIO_Mode = 	GPIO_Mode_IPU;	//IRQ pin should be Pull Down to prevent unnecessary EXT IRQ while DW1000 goes to sleep mode
    GPIO_Init(GD0IRQ_GPIO, &GPIO_InitStructure);

    /* Connect EXTI Line to GPIO Pin */
    GPIO_EXTILineConfig(GD0IRQ_EXTI_PORT, GD0IRQ_EXTI_PIN);

    /* Configure EXTI line */
    EXTI_InitStructure.EXTI_Line = GD0IRQ_EXTI;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;	//MPW3 IRQ polarity is high by default
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    return 0;
}

void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;

    CC1101_ISR_Configuration();

    /* Set NVIC Grouping to 16 groups of interrupt without sub-grouping */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

    /* Enable and set EXTI Interrupt to the lowest priority */
    NVIC_InitStructure.NVIC_IRQChannel = GD0IRQ_EXTI_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 15;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;

    NVIC_Init(&NVIC_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 15;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);
}
